<template>
  <el-dialog
    :model-value="modelValue"
    @close="close()"
    draggable
    :close-on-click-modal="false"
    :title="title"
    width="50%"
  >
    <el-input v-model="filterText" placeholder="请输入名称，按回车键【Enter】查询" />
    <el-scrollbar height="600px">
      <el-tree
        ref="treeRef"
        :data="roleMenulist"
        show-checkbox
        node-key="id"
        default-expand-all
        :expand-on-click-node="false"
        :check-on-click-node="true"
        :props="{
          children: 'children',
          label: 'name',
        }"
        :default-checked-keys="selectMenuIdList"
        :filter-node-method="filterNode"
        @check="menuChange"
        :check-strictly="true"
      >
        <template #default="{ node, data }">
          <span>
            <el-tag
              size="small"
              :type="
                data.menuType === MenuTypeEnum.Group
                  ? 'success'
                  : data.menuType === MenuTypeEnum.Menu
                    ? 'danger'
                    : data.menuType === MenuTypeEnum.List
                      ? 'warning'
                      : 'primary'
              "
            >
              {{ menuTypeFilter(data) }}
            </el-tag>
            <span>【{{ node.label }}】</span>
          </span>
        </template>
      </el-tree>
    </el-scrollbar>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="close()">取消</el-button>
        <el-button type="primary" @click="saveForm()" v-button="['api:sys:sysrolemenu:create']">
          确认
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import RoleMenuApi, { RoleMenu, RoleMenuCreate } from "@/api/sys/role/roleMenu";
import EnumApi, { EnumData } from "@/api/enums";
import { MenuTypeEnum } from "@/enums/MenuTypeEnum";

const props = defineProps({
  modelValue: Boolean,
  roleId: String,
  type: Number,
  title: String,
});

onMounted(async () => {
  await query();
  await getMenuTypeList();
});

const emits = defineEmits(["update:modelValue", "success"]);

const roleMenulist = ref<RoleMenu[]>([]);
const selectMenuIdList = ref([]);

const query = async () => {
  const { dataList, dataExt } = await RoleMenuApi.query(props.roleId);
  roleMenulist.value = dataList;
  selectMenuIdList.value = dataExt;
};

const menuTypeList = ref<EnumData[]>([]);
const getMenuTypeList = async () => {
  menuTypeList.value = await EnumApi.QueryMenuTypeEnums();
};

const menuChange = (menu: RoleMenu) => {
  const childIds = [menu.id];
  treeToList(childIds, menu.children);
  if (selectMenuIdList.value.indexOf(menu.id) !== -1) {
    for (let i = 0; i < childIds.length; i++) {
      const index = selectMenuIdList.value.indexOf(childIds[i]);
      if (index !== -1) {
        selectMenuIdList.value.splice(index, 1);
      }
    }
  } else {
    for (let i = 0; i < childIds.length; i++) {
      const index = selectMenuIdList.value.indexOf(childIds[i]);
      if (index === -1) {
        selectMenuIdList.value.push(childIds[i]);
      }
    }
  }
  treeRef.value.setCheckedKeys(selectMenuIdList.value);
};

const treeToList = (menuIds: String[], menu: RoleMenu[]) => {
  menu.forEach((element) => {
    menuIds.push(element.id);
    if (element.children && element.children.length > 0) {
      treeToList(menuIds, element.children);
    }
  });
};

const menuTypeFilter = computed(() => (item: RoleMenu) => {
  return menuTypeList.value.find((x) => x.value === item.menuType)?.text;
});

const filterText = ref("");
const treeRef = ref(ElTree);

watch(filterText, (val) => {
  treeRef.value!.filter(val);
});

const filterNode = (value: string, data: RoleMenu) => {
  if (!value) return true;
  return data.name.includes(value);
};

//提交数据
const saveForm = async () => {
  const roleMenu = reactive<RoleMenuCreate>({
    roleId: props.roleId,
    menuIdList: treeRef.value.getCheckedNodes(false, true).map((x) => x.id),
  });
  const { success, message } = await RoleMenuApi.create(roleMenu);
  if (success) {
    emits("success");
    ElNotification({
      title: message,
      type: "success",
    });
    close();
  } else {
    ElNotification({
      title: message,
      type: "error",
    });
  }
};

const close = () => {
  emits("update:modelValue");
};
</script>

<style></style>
